
/* -*-C-*-
 ##############################################################################
 #
 # File:        trice/src/trigger.c
 # RCS:         "@(#)$Revision: 1.19 $ $Date: 94/03/09 11:18:43 $"
 # Description: Routines for configuring trigger parameters on a E1430 module.
 # Author:      Doug Passey
 # Created:     
 # Language:    C
 # Package:     E1430
 # Status:      "@(#)$State: Exp $"
 #
 # (C) Copyright 1992, Hewlett-Packard Company, all rights reserved.
 #
 ##############################################################################
 #
 # Please add additional comments here
 #
 # Revisions:
 #
 ##############################################################################
*/

#    include <stdio.h>
#    include <math.h>

#include "trice.h"
#include "err1430.h"

#ifndef lint
const char i1430_trigger_fileId[] = "$Header: trigger.c,v 1.19 94/03/09 11:18:43 chriss Exp $";
#endif


/*****************************************************************************
 *
 * Save the trigger level bits into the module data structure.
 *
 ****************************************************************************/
static SHORTSIZ16 save_trigger_level_bits(SHORTSIZ16 groupID, SHORTSIZ16 source, 
							SHORTSIZ16 bits)
{
  SHORTSIZ16 mask;

  if(source == E1430_TRIGGER_SOURCE_ADC) {
    mask = TRIGGER_LEVEL_SAVE_ADC_MASK;
  }else{
    bits <<= TRIGGER_LEVEL_SAVE_MAG_BIT_SHIFT;
    mask = TRIGGER_LEVEL_SAVE_MAG_MASK;
  }

  return (i1430_update_group_module_bits(groupID, TRIGGER_LEVEL_SAVE, mask, bits));
}


/*****************************************************************************
 *
 * Returns in <bitsPtr> the register bits for each trigger mode in <mode>.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trig_source_bits(SHORTSIZ16 mode, SHORTSIZ16 *bitsPtr)
{
  switch(mode) {	
    case E1430_TRIGGER_SOURCE_OFF:
      *bitsPtr = TRIGGER_SETUP_TRIG_DISABLE;
      break;
    case E1430_TRIGGER_SOURCE_AUTO:
      *bitsPtr = TRIGGER_SETUP_TRIG_AUTO_ON | TRIGGER_SETUP_TRIG_ENABLE;
      break;
    case E1430_TRIGGER_SOURCE_EXT:
      *bitsPtr = TRIGGER_SETUP_TRIG_AUTO_OFF | TRIGGER_SETUP_SOURCE_EXT | 
		TRIGGER_SETUP_INTERNAL_ADC | TRIGGER_SETUP_TRIG_ENABLE;
      break;
    case E1430_TRIGGER_SOURCE_ADC:
      *bitsPtr = TRIGGER_SETUP_TRIG_AUTO_OFF | TRIGGER_SETUP_SOURCE_INT | 
			TRIGGER_SETUP_INTERNAL_ADC | TRIGGER_SETUP_TRIG_ENABLE;
      break;
    case E1430_TRIGGER_SOURCE_MAG:
      *bitsPtr = TRIGGER_SETUP_TRIG_AUTO_OFF | TRIGGER_SETUP_SOURCE_INT | 
			TRIGGER_SETUP_INTERNAL_MAG | TRIGGER_SETUP_TRIG_ENABLE;
      break;
    default:
      return (i1430_Error(ERR1430_ILLEGAL_TRIGGER_MODE, NULL, NULL));
  }

  return (0);
}


/*****************************************************************************
 *
 * Calculates the trigger level bits given level in terms of fraction of
 * full scale and whether triggering mode is ADC or MAGNITUDE.  The trigger
 * bits are returned in the location pointed to by bitPtr.
 * Returns 0 if all ok, else return negative error number.
 *
 * Formula for ADC level:  level = n/128 -1
 *
 * Formula for MAG level:  level = 2^(n-237)/16
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trig_level_bits(FLOATSIZ64 level, SHORTSIZ16 mode,
					SHORTSIZ16 *bitsPtr)
{
  FLOATSIZ64 temp;

  switch(mode) {
    case E1430_TRIGGER_SOURCE_ADC:		/* linear triggering */
      temp = (128.0 * (1.0 + level));
      if((SHORTSIZ16)(temp + 0.5) > (SHORTSIZ16)temp) { /* round up */
	temp = temp + 0.5;
      }

      if(temp < 0.0 ) temp = 0.0;
      if(temp > 255.0) temp = 255.0;

      *bitsPtr = (SHORTSIZ16)temp;
      break;
  
    case E1430_TRIGGER_SOURCE_MAG:		/* magnitude triggering */
      if(level > 3.0) {			/* trigger level outside dB range */
	level = 3.0;
      }

      if(level < -85.0) {
	level = -85.0;
      }

      temp = 237.0 + (8.0 * level)/3.0;	/* convert dB to internal units,
					 * 6dB = 16 internal units */

      *bitsPtr = (SHORTSIZ16)temp;
      break;
   
    default:
      return (i1430_Error(ERR1430_ILLEGAL_TRIGGER_MODE, NULL, NULL));
  }

  return (0);
}


/*****************************************************************************
 *
 * Returns in <bitsPtr> the register bits for each trigger slope in <slope>.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trig_slope_bits(SHORTSIZ16 slope, SHORTSIZ16 *bitsPtr)
{
  switch(slope) {	
    case E1430_TRIGGER_SLOPE_POS:
      *bitsPtr = TRIGGER_SETUP_SLOPE_POS;
      break;
    case E1430_TRIGGER_SLOPE_NEG:
      *bitsPtr = TRIGGER_SETUP_SLOPE_NEG;
      break;
    default:
      return (i1430_Error(ERR1430_ILLEGAL_TRIGGER_SLOPE, NULL, NULL));
  }

  return (0);
}


/*****************************************************************************
 *
 * Returns in <offsetHiPtr> and <offsetLoPtr> the register bits for 
 * corresponding to <delay> for the TRIGGER_OFFSET_LO_REG and the
 * TRIGGER_BLOCKSIZE_REG.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trig_delay_bits(SHORTSIZ16 groupID, LONGSIZ32 delay, 
			SHORTSIZ16 *offsetLoPtr, SHORTSIZ16 *offsetHiPtr)
{
  SHORTSIZ16 pack;
  SHORTSIZ16 error;
  LONGSIZ32 maxBlockSize;
  SHORTSIZ16 pointSize;

  error = i1430_get_group_data_pt_size(groupID, &pointSize);
  if(error) return(error);

  error = e1430_get_fifo_max_blocksize(groupID, &maxBlockSize);
  if(error) return (error);

  pack = 8/pointSize;		/* number of samples in 8 bytes */

  /* set PRETRIGGER bit by looking at sign of delay */
  if(delay < 0) { 	/* negative means pretrigger on */
    delay = -delay;	/* make delay bits positive */
    if(delay > maxBlockSize) {
      return(i1430_Error(ERR1430_PRETRIGGER_GREATER_FIFO, NULL, NULL));
    }
    *offsetHiPtr = TRIGGER_BLOCKSIZE_PRE_TRIGGER;
  }else{		/* pretrigger off */
    *offsetHiPtr = TRIGGER_BLOCKSIZE_POST_TRIGGER;
  }

  delay /= pack;		/* delay in terms of 8 byte chucks */
  if(delay >= (1L << 24) ) {
    return(i1430_Error(ERR1430_ILLEGAL_TRIGGER_DELAY, NULL, NULL));
  }

  *offsetHiPtr |= (SHORTSIZ16)((delay >> TRIGGER_BLOCKSIZE_HI_BIT_SHIFT) & 
					~TRIGGER_BLOCKSIZE_HI_OFFSET_MASK);

  *offsetLoPtr = (SHORTSIZ16)(delay & 0x0FFFFL);

  return (0);
}


/*****************************************************************************
 *
 * Set trigger parameters.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/


SHORTSIZ16 e1430_set_trigger_mode(SHORTSIZ16 groupID, SHORTSIZ16 source,
			LONGSIZ32 delay, FLOATSIZ64 threshold,
			SHORTSIZ16 slope)
{
  SHORTSIZ16 modSetupBits, bits;
  SHORTSIZ16 loBits, hiBits;
  SHORTSIZ16 error;
  SHORTSIZ16 mask;
  aModGroupPtr ptr;

  mask = TRIGGER_SETUP_SOURCE_MASK & TRIGGER_SETUP_SLOPE_MASK & 
	TRIGGER_SETUP_TRIG_AUTO_MASK & TRIGGER_SETUP_INTERNAL_MASK &
	TRIGGER_SETUP_TRIG_DISABLE_MASK;

  /* set bits for trigger parameters */
  error = i1430_get_trig_source_bits(source, &bits);
  if(error) return (error);

  modSetupBits = bits;

  /* set bits for trigger level, only in ADC or MAG triggering */
  switch(source) {
    case E1430_TRIGGER_SOURCE_ADC:
    case E1430_TRIGGER_SOURCE_MAG:
      error = i1430_get_trig_level_bits(threshold, source, &bits);
      if(error) return (error);

      modSetupBits |= bits;
      mask &= TRIGGER_SETUP_LEVEL_MASK;

      /*save level bits... MUST BE DONE PRIOR TO i1430_update_group_module_bits call*/
      error = save_trigger_level_bits(groupID, source, bits);
      if(error) return (error);
      break;

  }

  /* set slope bits */
  error = i1430_get_trig_slope_bits(slope, &bits);
  if(error) return (error);

  /* save slope bits ... MUST BE DONE PRIOR TO i1430_update_group_module_bits call */
  error = i1430_update_group_module_bits(groupID, TRIGGER_SLOPE_SAVE, 
					TRIGGER_SETUP_SLOPE_MASK, bits);
  if(error) return (error);

  modSetupBits |= bits;

  /* update E1430_TRIGGER_SETUP_REG */
  error = i1430_update_group_module_bits(groupID, E1430_TRIGGER_SETUP_REG, 
							mask, modSetupBits);
  if(error) return (error);

  /* save programmed trigger delay */
  if((ptr = i1430_valid_module_group(groupID)) == NULL) {/* no such group exists */
    return (ERR1430_NO_GROUP);
  }

  for(; *ptr != -1; ptr++) {
    e1430_modStates[*ptr].trigDelaySave = delay;
  }

  error = i1430_get_trig_delay_bits(groupID, delay, &loBits, &hiBits);
  if(error) return (error);

  mask = TRIGGER_BLOCKSIZE_HI_OFFSET_MASK & TRIGGER_BLOCKSIZE_PRE_POST_MASK;
  
  /* update E1430_TRIGGER_BLOCKSIZE_REG */
  error = i1430_update_group_module_bits(groupID, E1430_TRIGGER_BLOCKSIZE_REG, 
							mask, hiBits);
  if(error) return (error);
   
  return (i1430_update_group_module_bits(groupID, E1430_TRIGGER_OFFSET_LO_REG,
							0, loBits));
}


/*****************************************************************************
 *
 * Get trigger phase in terms of sample count.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trigger_phase_bits(SHORTSIZ16 la, LONGSIZ32 *phasePtr)
{
  SHORTSIZ16 error, data;
  LONGSIZ32 phasebits;
  
  /* get current counter */
  error = e1430_read_register_card(la, E1430_DECIMATION_CNTLAT_3_REG, &data);
  if(error) return (error);

  phasebits = ((LONGSIZ32)data & 0x1L) << 24;

  error = e1430_read_register_card(la, E1430_DECIMATION_CNTLAT_2_REG, &data);
  if(error) return (error);

  phasebits |= ((LONGSIZ32)data & 0x0FFL) << 16;

  error = e1430_read_register_card(la, E1430_DECIMATION_CNTLAT_1_REG, &data);
  if(error) return (error);

  phasebits |= ((LONGSIZ32)data & 0x0FFL) << 8;

  error = e1430_read_register_card(la, E1430_DECIMATION_CNTLAT_0_REG, &data);
  if(error) return (error);

  phasebits |= (LONGSIZ32)data & 0x0FFL;

  *phasePtr = phasebits;

  return (0);
}


/*****************************************************************************
 *
 * Get trigger phase.  Will calculate the total delay from the trigger event
 * to the first sample in a block and put the result in <phasePtr>.  This 
 * result is the number of output sample periods expressed as a 64 bit floating
 * point number to allow for the dynamic range necessary.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_trigger_phase(SHORTSIZ16 la, FLOATSIZ64 *phasePtr)
{
  SHORTSIZ16 precision, dataType, bytesPerSample, passout, decimate;
  SHORTSIZ16 reg, error, sign, shift, altCnt, ca;
  LONGSIZ32 course, courseAdj, inPerOut, trate, rate, tcnt, cnt, trigOffset;
  FLOATSIZ64 fine, latency, shiftCor, deciCor;

  error = e1430_read_register_image(la, E1430_DATA_FORMAT_REG, &reg);
  if(error) return(error);

  precision = ((reg & ~DATA_FORMAT_DATA_SIZE_MASK) == DATA_FORMAT_DATA_SIZE_32)
								? 1 : 0;

  dataType = ((reg&~DATA_FORMAT_DATA_TYPE_MASK)==DATA_FORMAT_DATA_TYPE_COMPLEX)
								? 1 : 0;

  decimate = ((reg & ~DATA_FORMAT_DECIMATE_MASK) == DATA_FORMAT_DECIMATE_ON)
								? 1 : 0;

  passout = (reg & ~DATA_FORMAT_PASSOUT_MASK) >> DATA_FORMAT_PASSOUT_BIT_SHIFT;

  bytesPerSample = 1 << (1 + precision + dataType);

  rate = 1 << (passout + decimate);

  inPerOut = ((8 * rate)/ bytesPerSample);
 
  if(passout == 0) {
    trate = 0;
  }else{
    trate = 1 << (passout - 1);
  }

  error = e1430_read_register_image(la, E1430_TRIGGER_BLOCKSIZE_REG, &reg);
  if(error) return(error);

  sign = ((reg & ~TRIGGER_BLOCKSIZE_PRE_POST_MASK) == 
				TRIGGER_BLOCKSIZE_POST_TRIGGER) ? 1 : -1;
 
    
  trigOffset = (reg & ~TRIGGER_BLOCKSIZE_HI_OFFSET_MASK) <<
						TRIGGER_BLOCKSIZE_HI_BIT_SHIFT;


  error = e1430_read_register_image(la, E1430_TRIGGER_OFFSET_LO_REG, &reg);
  if(error) return(error);

  trigOffset |= reg;
  trigOffset *= sign;

  /* read trigger phase register and get flags */
  error = i1430_get_trigger_phase_bits(la, &cnt);
  if(error) return(error);

  error = e1430_read_register_card(la, E1430_DECIMATION_CNTLAT_0_REG, &reg);
  if(error) return(error);

  shift = (reg & SHIFT_MASK) >> CNTLAT_BIT_SHIFT;

  altCnt = (reg & ALT_CNTLAT_MASK) ? 1 : 0;

  if(passout == 0) {
    cnt = decimate * altCnt;
    fine = (FLOATSIZ64)cnt / (FLOATSIZ64)rate;
  }else{
    cnt %= rate;
    fine = (FLOATSIZ64)(rate - cnt) / (FLOATSIZ64)rate;
  }

  /* calculate offset due to packing */
  ca = 0;

  if(trigOffset < 0) {
    ca = 1;
  }
  
  if(trigOffset > 0 && passout == 0) {
    if(inPerOut == 1) {
      ca = 1;
    }else{
      if(inPerOut == 2 && decimate == 0 && shift == 2) {
	ca = 1;
      }else{
	if(inPerOut == 2 && decimate == 1 && cnt == 0) {
	  ca = 1;
	}else{
	  if(inPerOut > 2 && decimate == 0 && shift == 0) {
	    ca = -1;
	  }else{
	    if(inPerOut > 2 && decimate == 1 && cnt == 1 && shift == 0) {
	      ca = -1;
	    }
	  }
	}
      }
    }
  }

  if((trigOffset > 0) && (passout == 1) && (inPerOut == 2) && (cnt == 1)) {
    ca = 1;
  }

  if((trigOffset > 0) && (0 < passout) && (passout < 5) && (inPerOut > 2) && 
			(cnt == ((rate - trate + 1) % rate)) && (shift == 0)) {
    ca = -1;
  }

  if((trigOffset > 0) && (passout > 4) && (cnt == ((rate - trate + 33) % rate))
						&& (shift == 0)) {
    ca = -1;
  }

  course = (8 * trigOffset) / bytesPerSample;

  courseAdj = (8 * ca) / bytesPerSample;

  latency = 2.0 / (FLOATSIZ64)rate;

  if(cnt > rate - trate) {
    latency -= 1.0;
  }

  if(passout > 4) {
    tcnt = (cnt - 1 + (rate / (1 << (decimate + 1)))) % rate;
  }else{
    tcnt = 32;
  }

  if(tcnt < 32) {
    latency += 1.0;
  }

  shiftCor = (FLOATSIZ64)(2 * shift) / (FLOATSIZ64)bytesPerSample;

  deciCor = (FLOATSIZ64)(decimate * trate) / (FLOATSIZ64)rate;

  *phasePtr = (FLOATSIZ64)(course + courseAdj) + deciCor 
						- shiftCor + fine - latency;
   
  return (0);
}


/*****************************************************************************
 *
 * Set trigger source in module group, <groupID>, to <source>.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_set_trigger_source(SHORTSIZ16 groupID, SHORTSIZ16 source)
{
  SHORTSIZ16 error, bits, mask;

  mask = TRIGGER_SETUP_TRIG_AUTO_MASK & TRIGGER_SETUP_INTERNAL_MASK & 
		TRIGGER_SETUP_SOURCE_MASK & TRIGGER_SETUP_TRIG_DISABLE_MASK;

  error = i1430_get_trig_source_bits(source, &bits);
  if(error) return (error);
  
  error = i1430_update_group_module_bits(groupID, E1430_TRIGGER_SETUP_REG,
					mask, bits);
  if(error) return (error);
  
  return (0);

}


/*****************************************************************************
 *
 * Set trigger slope in module group, <groupID>, to <slope>.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_set_trigger_slope(SHORTSIZ16 groupID, SHORTSIZ16 slope)
{
  SHORTSIZ16 error, bits;

  error = i1430_get_trig_slope_bits(slope, &bits);
  if(error) return (error);
  
  /* save slope bits ... MUST BE DONE PRIOR TO i1430_update_group_module_bits call */
  error = i1430_update_group_module_bits(groupID, TRIGGER_SLOPE_SAVE, 
					TRIGGER_SETUP_SLOPE_MASK, bits);
  if(error) return (error);

  return (i1430_update_group_module_bits(groupID, E1430_TRIGGER_SETUP_REG,
					TRIGGER_SETUP_SLOPE_MASK, bits));
}


/*****************************************************************************
 *
 * Set trigger level in module group, <groupID>, to <level>, where level is
 * interpreted as 0.0 -> 1.0 of full scale.  Save the level.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_set_trigger_level_adc(SHORTSIZ16 groupID, FLOATSIZ64 level)
{
  SHORTSIZ16 error, bits;
  SHORTSIZ16 reg, la;

  /* get current state of trigger register */
  error = i1430_get_first_la(groupID, &la);
  if(error) return(error);

  error = e1430_read_register_image(la, E1430_TRIGGER_SETUP_REG, &reg);
  if(error) return(error);

  /* get bits corresponding to this level */
  error = i1430_get_trig_level_bits(level, E1430_TRIGGER_SOURCE_ADC, &bits);
  if(error) return (error);

  /* save level bits... MUST BE DONE PRIOR TO i1430_update_group_module_bits call */
  error = save_trigger_level_bits(groupID, E1430_TRIGGER_SOURCE_ADC, bits);
  if(error) return (error);

  /* only update register if in ADC triggering */
  if((TRIGGER_SETUP_SOURCE_INT == (reg & ~TRIGGER_SETUP_SOURCE_MASK)) &&
     (TRIGGER_SETUP_INTERNAL_ADC == (reg & ~TRIGGER_SETUP_INTERNAL_MASK))) {
    error = i1430_update_group_module_bits(groupID, E1430_TRIGGER_SETUP_REG, 
					TRIGGER_SETUP_LEVEL_MASK, bits);
    if(error) return (error);
  }

  return (0);
}


/*****************************************************************************
 *
 * Set trigger level in module group, <groupID>, to <level>, where level is
 * interpreted as dB down from full scale.  Save the level.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_set_trigger_level_mag(SHORTSIZ16 groupID, FLOATSIZ64 level)
{
  SHORTSIZ16 error, bits;
  SHORTSIZ16 reg, la;

  /* get current state of trigger register */
  error = i1430_get_first_la(groupID, &la);
  if(error) return(error);

  error = e1430_read_register_image(la, E1430_TRIGGER_SETUP_REG, &reg);
  if(error) return(error);

  /* get bits corresponding to this level */
  error = i1430_get_trig_level_bits(level, E1430_TRIGGER_SOURCE_MAG, &bits);
  if(error) return (error);
 
  /* save level bits... MUST BE DONE PRIOR TO i1430_update_group_module_bits call */
  error = save_trigger_level_bits(groupID, E1430_TRIGGER_SOURCE_MAG, bits);
  if(error) return (error);

  /* only update register if in MAG triggering */
  if((TRIGGER_SETUP_SOURCE_INT == (reg & ~TRIGGER_SETUP_SOURCE_MASK)) &&
     (TRIGGER_SETUP_INTERNAL_MAG == (reg & ~TRIGGER_SETUP_INTERNAL_MASK))) {
    error = i1430_update_group_module_bits(groupID, E1430_TRIGGER_SETUP_REG, 
					TRIGGER_SETUP_LEVEL_MASK, bits);
    if(error) return (error);
  }

  return (0);
}


/*****************************************************************************
 *
 * Set trigger delay in module group, <groupID>, to <delay>.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_set_trigger_delay(SHORTSIZ16 groupID, LONGSIZ32 delay)
{
  SHORTSIZ16 error, loBits, hiBits, mask;
  aModGroupPtr ptr;

  error = i1430_get_trig_delay_bits(groupID, delay, &loBits, &hiBits);
  if(error) return (error);

  if((ptr = i1430_valid_module_group(groupID)) == NULL) {/* no such group exists */
    return (ERR1430_NO_GROUP);
  }

  for(; *ptr != -1; ptr++) {	/* save programmed trigger delay */
    e1430_modStates[*ptr].trigDelaySave = delay;
  }

  mask = TRIGGER_BLOCKSIZE_HI_OFFSET_MASK & TRIGGER_BLOCKSIZE_PRE_POST_MASK;
  
  /* update TRIGGER_BLOCKSIZE_REG */
  error = i1430_update_group_module_bits(groupID, E1430_TRIGGER_BLOCKSIZE_REG, 
							mask, hiBits);
  if(error) return (error);
   
  return (i1430_update_group_module_bits(groupID, E1430_TRIGGER_OFFSET_LO_REG,
							0, loBits));
}


/*****************************************************************************
 *
 * Returns trigger source for module with <index> in e1430_modStates array.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trigger_source_index(SHORTSIZ16 index)
{
  SHORTSIZ16 trigSetup = e1430_modStates[index].trigSetup;

  /* if not generating a trigger */
  if(TRIGGER_SETUP_TRIG_DISABLE == 
			(trigSetup & ~TRIGGER_SETUP_TRIG_DISABLE_MASK)) {
    return (E1430_TRIGGER_SOURCE_OFF);
  }

  /* if auto trigger */
  if(TRIGGER_SETUP_TRIG_AUTO_ON == 
			(trigSetup & ~TRIGGER_SETUP_TRIG_AUTO_MASK)) {
    return (E1430_TRIGGER_SOURCE_AUTO);
  }

  if(TRIGGER_SETUP_SOURCE_EXT == (trigSetup & ~TRIGGER_SETUP_SOURCE_MASK)) {
    return (E1430_TRIGGER_SOURCE_EXT);
  }
    
  if(TRIGGER_SETUP_INTERNAL_ADC == (trigSetup&~TRIGGER_SETUP_INTERNAL_MASK)) {
    return (E1430_TRIGGER_SOURCE_ADC);
  }else{
   return (E1430_TRIGGER_SOURCE_MAG);
  }
}


/*****************************************************************************
 *
 * Returns the trigger source of the module group, <groupID>, into
 * the variable pointed to by <sourcePtr>.  
 * Returns 0 if OK, returns ERR1430_PARAMETER_UNEQUAL if the source is
 * not the same for all modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_trigger_source(SHORTSIZ16 groupID, SHORTSIZ16 *sourcePtr)
{ 
  return (i1430_get_short_parm(groupID, i1430_get_trigger_source_index, 
				"trigger source", sourcePtr));
}
 

/*****************************************************************************
 *
 * Returns trigger slope for module with <index> in e1430_modStates array.
 * Returns 0 if all ok, else return negative error number.
 *
 ****************************************************************************/
SHORTSIZ16 i1430_get_trigger_slope_index(SHORTSIZ16 index)
{
  switch(e1430_modStates[index].trigSlopeSave) {
    case TRIGGER_SETUP_SLOPE_POS:
      return (E1430_TRIGGER_SLOPE_POS);
    case TRIGGER_SETUP_SLOPE_NEG:
      return (E1430_TRIGGER_SLOPE_NEG);
    default:
      return (i1430_Error(ERR1430_ILLEGAL_TRIGGER_SLOPE, NULL, NULL));
  }
}


/*****************************************************************************
 *
 * Returns the trigger slope of the module group, <groupID>, into
 * the variable pointed to by <slopePtr>.  
 * Returns 0 if OK, returns ERR1430_PARAMETER_UNEQUAL if the slope is
 * not the same for all modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_trigger_slope(SHORTSIZ16 groupID, SHORTSIZ16 *slopePtr)
{ 
  return (i1430_get_short_parm(groupID, i1430_get_trigger_slope_index, 
				"trigger slope", slopePtr));
}
 

/*****************************************************************************
 *
 * Get ADC trigger level for module with <index> in e1430_modStates array,
 * value is fraction of full scale (-1.0 -> 1.0).
 *
 ****************************************************************************/
FLOATSIZ64 i1430_get_trig_lev_adc_index(SHORTSIZ16 index)
{
  SHORTSIZ16 trigLevel = e1430_modStates[index].trigLevelSave;
  SHORTSIZ16 level = trigLevel & ~TRIGGER_LEVEL_SAVE_ADC_MASK;

  return (((FLOATSIZ64)(level)/128.0) - 1.0);
}


/*****************************************************************************
 *
 * Returns the ADC trigger level of the module group, <groupID>, into
 * the variable pointed to by <levelPtr>.  
 * Returns 0 if OK, returns ERR1430_PARAMETER_UNEQUAL if the delay is
 * not the same for all modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_trigger_level_adc(SHORTSIZ16 groupID, FLOATSIZ64 *levelPtr)
{
  return (i1430_get_float_parm(groupID, i1430_get_trig_lev_adc_index, 
				"ADC trigger level", levelPtr));
}


/*****************************************************************************
 *
 * Get magnitude trigger level for module with <index> in e1430_modStates array,
 * value is in dBs from full scale
 *
 ****************************************************************************/
FLOATSIZ64 i1430_get_trig_lev_mag_index(SHORTSIZ16 index)
{
  SHORTSIZ16 trigLevel = e1430_modStates[index].trigLevelSave;
  SHORTSIZ16 level = (trigLevel & ~TRIGGER_LEVEL_SAVE_MAG_MASK) >>
					TRIGGER_LEVEL_SAVE_MAG_BIT_SHIFT;

  return (((FLOATSIZ64)(level - 237) * 3.0)/8.0);
}


/*****************************************************************************
 *
 * Returns the magnitude trigger level of the module group, <groupID>, into
 * the variable pointed to by <levelPtr>.  
 * Returns 0 if OK, returns ERR1430_PARAMETER_UNEQUAL if the delay is
 * not the same for all modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_trigger_level_mag(SHORTSIZ16 groupID, FLOATSIZ64 *levelPtr)
{ 
  return (i1430_get_float_parm(groupID, i1430_get_trig_lev_mag_index, 
				"Mag trigger level", levelPtr));
}


/*****************************************************************************
 *
 * Returns trigger delay for module with <index> in e1430_modStates array.
 * not in one of the internal trigger modes, return 0.0.
 *
 ****************************************************************************/
LONGSIZ32 i1430_get_trigger_delay_index(SHORTSIZ16 index)
{
  SHORTSIZ16 hi;
  LONGSIZ32 temp;
  SHORTSIZ16 la;
  SHORTSIZ16 error;
  SHORTSIZ16 pointSize;
  SHORTSIZ16 pack;

  la = e1430_modStates[index].logicalAddr;

  error = e1430_get_fifo_data_point_size(la, &pointSize);
  if(error) return(error);

  pack = 8/pointSize;		/* number of points in 8 byte chuck */

  hi =  e1430_modStates[index].trigBlocksize & ~TRIGGER_BLOCKSIZE_HI_OFFSET_MASK;

  temp = ((LONGSIZ32)hi) << TRIGGER_BLOCKSIZE_HI_BIT_SHIFT;
  temp += 0xFFFFL & (LONGSIZ32)e1430_modStates[index].trigOffset;
  temp *= (LONGSIZ32)pack;

  if(TRIGGER_BLOCKSIZE_PRE_TRIGGER == 
	(e1430_modStates[index].trigBlocksize & ~TRIGGER_BLOCKSIZE_PRE_POST_MASK)) {
    temp = -temp;
  }

  return (temp);
}


/*****************************************************************************
 *
 * Returns the trigger delay of the module group, <groupID>, into
 * the variable pointed to by <delayPtr>.  
 * Returns 0 if OK, returns ERR1430_PARAMETER_UNEQUAL if the delay is
 * not the same for all modules in the group.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_get_trigger_delay(SHORTSIZ16 groupID, LONGSIZ32 *delayPtr)
{ 
  return (i1430_get_long_parm(groupID, i1430_get_trigger_delay_index, 
				"trigger delay", delayPtr));
}
